package com.huixuebao.after.service.impl;


import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.api.R;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.huixuebao.after.dto.MechanismRoleDTO;
import com.huixuebao.after.dto.RoleDTO;
import com.huixuebao.after.dto.RoleFunctionDTO;
import com.huixuebao.after.dto.RoleIdDTO;
import com.huixuebao.after.entity.*;
import com.huixuebao.after.mapper.*;
import com.huixuebao.after.service.MachanismService;
import com.huixuebao.after.service.RoleService;
import com.huixuebao.common.bean.ApiResult;
import com.huixuebao.common.enumeration.ResultCodeEnum;
import com.huixuebao.common.util.ConvertUtils;
import com.huixuebao.common.util.JWTUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class RoleServiceImpl implements RoleService {

    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private RoleFunctionMapper roleFunctionMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private MechanismRoleMapper mechanismRoleMapper;

    /**
     * 添加角色/菜单
     * @param roleFunctionDTO
     * @return
     */
    @Override
    public ApiResult addRoleFunction(@RequestBody RoleFunctionDTO roleFunctionDTO,HttpServletRequest request) {

        ApiResult apiResult = new ApiResult();
        String userType = JWTUtils.getUserType(request);
        String userId = JWTUtils.getUserId(request);
        try {
            //角色名称
            String roleName = roleFunctionDTO.getRoleName();
            String perStr = roleFunctionDTO.getPerStr();
            //角色显示顺序
            String showSort = roleFunctionDTO.getShowSort();
            //角色状态
            String status = roleFunctionDTO.getStatus();
            //角色描述
            String remark = roleFunctionDTO.getRemark();
            //菜单id
            List<Object> funcIds = Arrays.asList(roleFunctionDTO.getFuncIds().toString().split(","));
            if (CollectionUtils.isNotEmpty(funcIds)) {
                if (StrUtil.isNotEmpty(roleName) && StrUtil.isNotEmpty(status) && StrUtil.isNotEmpty(remark)) {
                    if ("0".equals(userType)) {
                        RoleEntity roles = new RoleEntity();
                        roles.setRoleName(roleName);
                        roles.setPerStr(perStr);
                        roles.setStatus(status);
                        roles.setRemark(remark);
                        roles.setCreateTime(new DateTime());
                        roleMapper.insert(roles);
                        String roleId = roles.getId();
                        funcIds.forEach(funcId -> {
                            log.info("save webRoleFunc roleId={},funcId={}:", roleId, funcId.toString());
                            RoleFunctionEntity roleFunction = new RoleFunctionEntity();
                            roleFunction.setFunId(funcId.toString());
                            roleFunction.setRoleId(roleId);
                            roleFunctionMapper.insert(roleFunction);

                        });
                        Map<String, Object> result = new HashMap<>();
                        result.put("roleName", roles.getRoleName());
                        result.put("perStr", roles.getPerStr());
                        result.put("createTime", roles.getCreateTime());
                        result.put("remark", roles.getRemark());
                        result.put("status", roles.getStatus());
                        result.put("roleId", roleId);
                        result.put("funIds", funcIds);
                        //apiResult.setContent(result);
                        apiResult.setSuccess(true);
                        apiResult.setCode(ResultCodeEnum.SUCCESS.getCode());
                        apiResult.setMessage("添加角色成功！！");
                        //}
                    } else {
                        //usertype是机构端端时候进行下面操作
                        RoleEntity roles = new RoleEntity();
                        roles.setRoleName(roleName);
                        roles.setPerStr(perStr);
                        roles.setStatus(status);
                        roles.setRemark(remark);
                        roles.setCreateTime(new DateTime());
                        roleMapper.insert(roles);
                        String roleId = roles.getId();
                        funcIds.forEach(funcId -> {
                            log.info("save webRoleFunc roleId={},funcId={}:", roleId, funcId.toString());
                            RoleFunctionEntity roleFunction = new RoleFunctionEntity();
                            roleFunction.setFunId(funcId.toString());
                            roleFunction.setRoleId(roleId);
                            roleFunctionMapper.insert(roleFunction);

                        });
                        //将角色添加到机构关联表中
                        UserEntity mechanismId = userMapper.selectOne(new LambdaQueryWrapper<UserEntity>().eq(UserEntity::getId,userId));
                        MechanismRoleEntity mechanismRoleEntity = new MechanismRoleEntity();
                        mechanismRoleEntity.setMechanismId(mechanismId.getMechanismId());
                        mechanismRoleEntity.setRoleId(roleId);
                        mechanismRoleMapper.insert(mechanismRoleEntity);
                        Map<String, Object> result = new HashMap<>();
                        result.put("roleName", roles.getRoleName());
                        result.put("perStr", roles.getPerStr());
                        result.put("createTime", roles.getCreateTime());
                        result.put("remark", roles.getRemark());
                        result.put("status", roles.getStatus());
                        result.put("roleId", roleId);
                        result.put("funIds", funcIds);
                        apiResult.setSuccess(true);
                        apiResult.setCode(ResultCodeEnum.SUCCESS.getCode());
                        apiResult.setMessage("添加角色成功！！");
                    }
                } else {
                    apiResult.setSuccess(false);
                    apiResult.setCode(ResultCodeEnum.SUCCESS.getCode());
                    apiResult.setMessage("必填字段不能为空！！");
                }
            } else {
                apiResult.setSuccess(false);
                apiResult.setCode(ResultCodeEnum.SUCCESS.getCode());
                apiResult.setMessage("角色管理的菜单信息不能为空!!");
            }
        } catch (Exception e) {
            log.info("添加角色信息异常!!", e);
            apiResult.setSuccess(false);
            apiResult.setCode(ResultCodeEnum.FAILURE.getCode());
            apiResult.setMessage("添加角色信息异常!!");
        }
        return apiResult;
    }
    /**
     * 编辑角色管理、角色信息、菜单
     * @param roleFunctionDTO
     * @return
     */
    @Override
    public ApiResult editRoleFunction(@RequestBody RoleFunctionDTO roleFunctionDTO){
        ApiResult apiResult = new ApiResult();
        try {
            //角色id
            String roleId = roleFunctionDTO.getId();

            String perStr = roleFunctionDTO.getPerStr();
            //角色显示顺序
            String showSort = roleFunctionDTO.getShowSort();
            //角色名称
            String roleNames = roleFunctionDTO.getRoleName();
            //角色状态
            String status = roleFunctionDTO.getStatus();
            //角色描述
            String remark = roleFunctionDTO.getRemark();
            List<Object> funcIds = Arrays.asList(roleFunctionDTO.getFuncIds().toString().split(","));
            //判断账号名称是否被占用
            int count = roleMapper.selectCount(new LambdaQueryWrapper<RoleEntity>().eq(RoleEntity::getId, roleId));
            if (count > 0 ) {
                if (StrUtil.isNotEmpty(roleId) || CollectionUtils.isNotEmpty(funcIds) || StrUtil.isNotEmpty(roleNames)) {
                    RoleEntity webRole = roleMapper.selectOne(new LambdaQueryWrapper<RoleEntity>().eq(RoleEntity::getId, roleId));
                    if (webRole == null) {
                        apiResult.setSuccess(false);
                        apiResult.setCode(ResultCodeEnum.FAILURE.getCode());
                        apiResult.setMessage("当前角色为空");
                    } else {
                        //更新角色信息
                        webRole.setRoleName(roleNames);
                        webRole.setUpdateTime(new DateTime());
                        webRole.setRemark(remark);
                        webRole.setShowSort(showSort);
                        webRole.setStatus(status);
                        webRole.setPerStr(perStr);
                        roleMapper.updateById(webRole);
                        // 清空角色菜单关联关系
                        roleFunctionMapper.delete(new LambdaQueryWrapper<RoleFunctionEntity>().eq(RoleFunctionEntity::getRoleId, roleId));
                        // 重新插入角色菜单关联关系
                        funcIds.forEach(funcId -> {
                            log.info("save webRoleFunc roleId={}, funcId={}", roleId, funcId.toString());
                            RoleFunctionEntity roleFunctionEntity = new RoleFunctionEntity();
                            roleFunctionEntity.setFunId(funcId.toString());
                            roleFunctionEntity.setRoleId(roleId);
                            roleFunctionMapper.insert(roleFunctionEntity);
                        });
                        apiResult.setSuccess(true);
                        apiResult.setCode(ResultCodeEnum.SUCCESS.getCode());
                        apiResult.setMessage("编辑角色成功!!");
                    }
                } else {
                    apiResult.setSuccess(false);
                    apiResult.setMessage("当前必填字段不能为空!!");
                }
            }else {
                log.info("当前角色id为空");
                apiResult.setSuccess(true);
                apiResult.setCode(ResultCodeEnum.FAILURE.getCode());
                apiResult.setMessage("未获取到角色id");
            }
        }catch (Exception e){
            log.info("异常信息", e);
            apiResult.setSuccess(false);
        }
        return apiResult;
    }

    @Override
    public ApiResult deleteRoleFunction(@RequestBody RoleIdDTO id) {
        ApiResult apiResult = new ApiResult();
        String roleId = id.getId();
        try {
            //1、根据roleId角色Id删除角色
            if (roleId != null) {
                roleFunctionMapper.delete(new LambdaQueryWrapper<RoleFunctionEntity>().eq(RoleFunctionEntity::getRoleId, roleId));
                roleMapper.deleteById(roleId);
                mechanismRoleMapper.delete(new LambdaQueryWrapper<MechanismRoleEntity>().eq(MechanismRoleEntity::getRoleId,roleId));
                apiResult.setSuccess(true);
                apiResult.setCode(ResultCodeEnum.SUCCESS.getCode());
                apiResult.setMessage("删除角色信息成功！！");
            } else {
                log.info("当前角色id为空！！");
                apiResult.setSuccess(false);
                apiResult.setCode(ResultCodeEnum.FAILURE.getCode());
                apiResult.setMessage("当前角色id为空");
            }
        } catch (Exception e) {
            apiResult.setSuccess(false);
            apiResult.setCode(ResultCodeEnum.FAILURE.getCode());
            log.info("删除角色，及角色菜单出现异常", e);
            apiResult.setMessage("删除角色，及角色菜单出现异常");
        }
        return apiResult;
    }
    /**
     * 获取角色名称
     * @return
     */
    @GetMapping("/getRoleName")
    public ApiResult getRoleName(){
        ApiResult apiResult = new ApiResult();
        try{
            List<RoleEntity>  roles = roleMapper.selectList(null);
            List<RoleDTO> result = new ArrayList<>(roles.size());
            roles.forEach(role ->{
                RoleDTO roleDTO = new RoleDTO();
                roleDTO.setId(role.getId());
                roleDTO.setRoleName(role.getRoleName());
                result.add(roleDTO);
            });
            apiResult.setData(result);
        }catch (Exception e){
            log.info("获取角色名称失败！！");
            apiResult.setSuccess(false);
            apiResult.setCode(ResultCodeEnum.FAILURE.getCode());
            apiResult.setMessage("获取角色名称失败");
        }
        return apiResult;
    }

    /**
     * 角色列表
     * @param current
     * @param size
     * @param roleName
     * @param roleState
     * @return
     */
    @Override
    public ApiResult getRoleList(Integer current, Integer size, String roleName, Integer roleState, HttpServletRequest request) {
        ApiResult apiResult = new ApiResult();
        try {
            String userId = JWTUtils.getUserId(request);
            String userType = JWTUtils.getUserType(request);
            if (ObjectUtil.isNotNull(current) && ObjectUtil.isNotNull(size)) {
                if ("0".equals(userType)) {
                    IPage<RoleEntity> page = new Page<>(current, size);
                    IPage<RoleEntity> entityIPage = roleMapper.selectPage(page, new LambdaQueryWrapper<RoleEntity>().orderByDesc(RoleEntity::getCreateTime)
                            .like(StrUtil.isNotBlank(roleName), RoleEntity::getRoleName, roleName)
                            .like(roleState != null, RoleEntity::getStatus, roleState));

                    entityIPage.getRecords().forEach(entity -> {
                        List<RoleFunctionEntity> list = roleFunctionMapper.selectList(new LambdaQueryWrapper<RoleFunctionEntity>().eq(RoleFunctionEntity::getRoleId, entity.getId()));
                        List<String> funcIds = list.stream().map(RoleFunctionEntity::getFunId).collect(Collectors.toList());
                        entity.setFuncIds(funcIds);
                    });
                    IPage<RoleDTO> dtoPage = ConvertUtils.convertToDTOPage(entityIPage, RoleDTO.class);
                    apiResult.setData(dtoPage);
                    apiResult.setSuccess(true);
                    apiResult.setCode(ResultCodeEnum.SUCCESS.getCode());
                    apiResult.setMessage("机构端查询角色分页查询列表成功！！");
                } else {
                    IPage<RoleEntity> page = new Page<>(current, size);
                    UserEntity mechanismId = userMapper.selectOne(new LambdaQueryWrapper<UserEntity>().eq(UserEntity::getId, userId));
                    List<MechanismRoleEntity> mechanismRole = mechanismRoleMapper.selectList(new LambdaQueryWrapper<MechanismRoleEntity>().eq(MechanismRoleEntity::getMechanismId, mechanismId.getMechanismId()));

                    List<String> roleIds = mechanismRole.stream().map(MechanismRoleEntity::getRoleId).collect(Collectors.toList());
                    IPage<RoleDTO> dtoPage = null;
                    if (roleIds.size() > 0) {
                        IPage<RoleEntity> entityIPages = roleMapper.selectPage(page, new LambdaQueryWrapper<RoleEntity>().in(roleIds.size()>0,RoleEntity::getId, roleIds).orderByDesc(RoleEntity::getCreateTime)
                                .like(StrUtil.isNotBlank(roleName), RoleEntity::getRoleName, roleName)
                                .like(roleState != null, RoleEntity::getStatus, roleState));

                        entityIPages.getRecords().forEach(entity -> {
                            List<RoleFunctionEntity> list = roleFunctionMapper.selectList(new LambdaQueryWrapper<RoleFunctionEntity>().eq(RoleFunctionEntity::getRoleId, entity.getId()));
                            List<String> funcIds = list.stream().map(RoleFunctionEntity::getFunId).collect(Collectors.toList());
                            entity.setFuncIds(funcIds);
                        });
                        dtoPage = ConvertUtils.convertToDTOPage(entityIPages, RoleDTO.class);
                    }

                    apiResult.setData(dtoPage);
                    apiResult.setSuccess(true);
                    apiResult.setCode(ResultCodeEnum.SUCCESS.getCode());
                    apiResult.setMessage("管理端查询角色分页查询列表成功！！");
                }
            } else {
                if ("0".equals(userType)) {
                    List<RoleEntity> list = roleMapper.selectList(null);
                    List<RoleDTO> dtoList = ConvertUtils.convertToDTOList(list, RoleDTO.class);
                    apiResult.setData(dtoList);
                    apiResult.setSuccess(true);
                    apiResult.setCode(ResultCodeEnum.SUCCESS.getCode());
                    apiResult.setMessage("角色信息统一返回成功！！");
                } else {
                    UserEntity userMechanism = userMapper.selectOne(new LambdaQueryWrapper<UserEntity>().eq(UserEntity::getId, userId));
                    List<MechanismRoleEntity> mechanismRoleEntity = mechanismRoleMapper.selectList(new LambdaQueryWrapper<MechanismRoleEntity>().eq(MechanismRoleEntity::getMechanismId, userMechanism.getMechanismId()));
                    List<String> roleIds = mechanismRoleEntity.stream().map(MechanismRoleEntity::getRoleId).collect(Collectors.toList());
                    List<RoleEntity> entityIPages = roleMapper.selectList(new LambdaQueryWrapper<RoleEntity>().in(roleIds.size()>0,RoleEntity::getId, roleIds).orderByDesc(RoleEntity::getCreateTime));
                    entityIPages.forEach(entity -> {
                        List<RoleFunctionEntity> list = roleFunctionMapper.selectList(new LambdaQueryWrapper<RoleFunctionEntity>().eq(RoleFunctionEntity::getRoleId, entity.getId()));
                        List<String> funcIds = list.stream().map(RoleFunctionEntity::getFunId).collect(Collectors.toList());
                        entity.setFuncIds(funcIds);
                    });
                    List<RoleDTO> dtoList = ConvertUtils.convertToDTOList(entityIPages, RoleDTO.class);
                    apiResult.setData(dtoList);
                    apiResult.setSuccess(true);
                    apiResult.setCode(ResultCodeEnum.SUCCESS.getCode());
                    apiResult.setMessage("商户/机构角色信息统一返回成功！！");
                }
            }
        } catch (Exception e) {
            apiResult.setSuccess(false);
            apiResult.setCode(ResultCodeEnum.FAILURE.getCode());
            apiResult.setMessage("查询角色列表失败！！");
        }
        return apiResult;
    }
}
